package http

import (
	"context"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"learn-go-demo/pkg/models"
	pb "learn-go-demo/proto"
)

type OrderHandler struct {
	orderRepo  *models.OrderRepository
	userClient pb.UserServiceClient
}

func NewOrderHandler(orderRepo *models.OrderRepository, userClient pb.UserServiceClient) *OrderHandler {
	return &OrderHandler{
		orderRepo:  orderRepo,
		userClient: userClient,
	}
}

type CreateOrderRequest struct {
	UserID  int64   `json:"user_id" binding:"required"`
	Product string  `json:"product" binding:"required"`
	Amount  float64 `json:"amount" binding:"required,min=0"`
}

type OrderResponse struct {
	ID      int64   `json:"id"`
	UserID  int64   `json:"user_id"`
	Product string  `json:"product"`
	Amount  float64 `json:"amount"`
	Status  string  `json:"status"`
}

type CreateOrderResponse struct {
	ID      int64  `json:"id"`
	Message string `json:"message"`
}

// CreateOrder 创建订单
// @Summary 创建订单
// @Description 创建新订单
// @Tags orders
// @Accept json
// @Produce json
// @Param order body CreateOrderRequest true "订单信息"
// @Success 201 {object} CreateOrderResponse
// @Failure 400 {object} gin.H
// @Failure 404 {object} gin.H
// @Failure 500 {object} gin.H
// @Router /orders [post]
func (h *OrderHandler) CreateOrder(c *gin.Context) {
	var req CreateOrderRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 验证用户是否存在
	if h.userClient != nil {
		_, err := h.userClient.GetUser(context.Background(), &pb.GetUserRequest{
			Id: int32(req.UserID),
		})
		if err != nil {
			c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
			return
		}
	}

	order := &models.Order{
		UserID:  req.UserID,
		Product: req.Product,
		Amount:  req.Amount,
		Status:  "pending",
	}

	if err := h.orderRepo.Create(order); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create order"})
		return
	}

	c.JSON(http.StatusCreated, CreateOrderResponse{
		ID:      order.ID,
		Message: "Order created successfully",
	})
}

// GetOrder 获取订单
// @Summary 获取订单
// @Description 根据ID获取订单信息
// @Tags orders
// @Produce json
// @Param id path int true "订单ID"
// @Success 200 {object} OrderResponse
// @Failure 400 {object} gin.H
// @Failure 404 {object} gin.H
// @Router /orders/{id} [get]
func (h *OrderHandler) GetOrder(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid order ID"})
		return
	}

	order, err := h.orderRepo.GetByID(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Order not found"})
		return
	}

	c.JSON(http.StatusOK, OrderResponse{
		ID:      order.ID,
		UserID:  order.UserID,
		Product: order.Product,
		Amount:  order.Amount,
		Status:  order.Status,
	})
}

// GetOrdersByUser 获取用户的订单列表
// @Summary 获取用户订单
// @Description 根据用户ID获取订单列表
// @Tags orders
// @Produce json
// @Param user_id path int true "用户ID"
// @Success 200 {array} OrderResponse
// @Failure 400 {object} gin.H
// @Failure 500 {object} gin.H
// @Router /orders/user/{user_id} [get]
func (h *OrderHandler) GetOrdersByUser(c *gin.Context) {
	userIDStr := c.Param("user_id")
	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
		return
	}

	orders, err := h.orderRepo.GetByUserID(userID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get orders"})
		return
	}

	var response []OrderResponse
	for _, order := range orders {
		response = append(response, OrderResponse{
			ID:      order.ID,
			UserID:  order.UserID,
			Product: order.Product,
			Amount:  order.Amount,
			Status:  order.Status,
		})
	}

	c.JSON(http.StatusOK, response)
}

// UpdateOrderStatus 更新订单状态
// @Summary 更新订单状态
// @Description 更新订单状态
// @Tags orders
// @Accept json
// @Produce json
// @Param id path int true "订单ID"
// @Param status body map[string]string true "状态信息"
// @Success 200 {object} gin.H
// @Failure 400 {object} gin.H
// @Failure 404 {object} gin.H
// @Failure 500 {object} gin.H
// @Router /orders/{id}/status [put]
func (h *OrderHandler) UpdateOrderStatus(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid order ID"})
		return
	}

	var req map[string]string
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	status, ok := req["status"]
	if !ok || status == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Status is required"})
		return
	}

	if err := h.orderRepo.UpdateStatus(id, status); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update order status"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Order status updated successfully"})
}
